package com.ruoyi.common.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @ProjectName: les
 * @Package: com.zkzn.les.wms.util
 * @ClassName: RedisNoUtil
 * @Author: 胡志明
 * @Description:
 * @Date: 2021/5/17 15:22
 */
public class RedisNoUtil {

    //排队号
    public static final String TASK_NUMBER = "task_number";
    //运营需求单
    public static final String YG = "YG";
    //SequenceService类中公用部分，传入制定的key和prefix
    public static String getSeqNo(String key, RedisTemplate redisTemplate) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.HOUR_OF_DAY, 23);
//        calendar.set(Calendar.MINUTE, 59);
//        calendar.set(Calendar.SECOND, 59);
//        calendar.set(Calendar.MILLISECOND, 999);
//        //设置过期时间，这里设置为当天的23:59:59
//        Date expireDate = calendar.getTime();
        //返回当前redis中的key的最大值
        Long seq = generate(redisTemplate, key);
        //获取当天的日期，格式为yyyyMMdd
        //String date = new SimpleDateFormat("yyyyMMdd").format(expireDate);
        //生成六位的序列号，如果seq不够六位，seq前面补0，
        //如果seq位数超过了六位，那么无需补0直接返回当前的seq
        String sequence = StringUtils.leftPad(seq.toString(), 3, "0");
        //拼接业务编号
        //String seqNo = key + date + sequence;
        return sequence;
    }

    //SequenceService类中公用部分，传入制定的key和prefix
    public static String getAddNo(String key, RedisTemplate redisTemplate) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        //设置过期时间，这里设置为当天的23:59:59
        Date expireDate = calendar.getTime();
        //返回当前redis中的key的最大值
        Long seq = newGenerate(redisTemplate,key,expireDate);
        //获取当天的日期，格式为yyyyMMdd
        String date = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
        //生成六位的序列号，如果seq不够六位，seq前面补0，
        //如果seq位数超过了六位，那么无需补0直接返回当前的seq
        String sequence = StringUtils.leftPad(seq.toString(), 2, "0");
        //拼接业务编号
        String seqNo = key + date + sequence;
        return seqNo;
    }

    /**
     * @return
     */
    public static long generate(RedisTemplate<?,?> redisTemplate, String key) {
        //RedisAtomicLong为原子类，根据传入的key和redis链接工厂创建原子类
        RedisAtomicLong counter = new RedisAtomicLong(key,redisTemplate.getConnectionFactory());
        //设置过期时间
        //counter.expireAt(expireTime);
        //返回redis中key的值，内部实现下面详细说明
        return counter.incrementAndGet();
    }

    /**
     * @param key
     * @param expireTime <i>过期时间</i>
     * @return
     */
    public static long newGenerate(RedisTemplate<?,?> redisTemplate, String key,Date expireTime) {
        //RedisAtomicLong为原子类，根据传入的key和redis链接工厂创建原子类
        RedisAtomicLong counter = new RedisAtomicLong(key,redisTemplate.getConnectionFactory());
        //设置过期时间
        counter.expireAt(expireTime);
        //返回redis中key的值，内部实现下面详细说明
        return counter.incrementAndGet();
    }

    /***
     * @Discription: 获取带有过期时间的自增涨值
     * @param key
     * @param redisTemplate
     * @return java.lang.Long
     * @Author: zhanglei on 2021/6/15 13:27
     */
    public static Long getSeqNoByExpireTime(String key, RedisTemplate redisTemplate, long expiresTime) {
        RedisAtomicLong counter = new RedisAtomicLong(key,redisTemplate.getConnectionFactory());
        counter.expire(expiresTime, TimeUnit.MILLISECONDS);
        return counter.incrementAndGet();
    }

    /***
     * @Discription: TTl到每天凌晨
     * @param
     * @return java.lang.Long
     * @Author: zhanglei on 2021/6/15 13:29
     */
    public static long getSecondsNextEarlyMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTimeInMillis() - System.currentTimeMillis();
    }

    /***
     * @Discription: 排队号时间获取 每天凌晨更新排队序列
     * @param key
     * @param redisTemplate
     * @return long
     * @Author: zhanglei on 2021/6/15 13:31
     */
    public static long getSeqNoByExpireTime(String key, RedisTemplate redisTemplate) {
        long secondsNextEarlyMorning = getSecondsNextEarlyMorning();
        return getSeqNoByExpireTime(key,redisTemplate,secondsNextEarlyMorning);
    }

    /**获取业务自增长编码**/
    public static String getOrderCode(String businessKey, RedisTemplate redisTemplate){
        //redis自增编码
        long seqNoByExpireTime = getSeqNoByExpireTime(businessKey, redisTemplate);
        String sequence = StringUtils.leftPad(String.valueOf(seqNoByExpireTime), 3, "0");
        //日期
        String date = new SimpleDateFormat("yyMMdd").format(new Date());
        //编码+日期拼接
        String orderCode = date.concat(String.valueOf(sequence));
        return orderCode;
    }
}
